package ui.swing.tree.eventhandle;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Enumeration;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

import ui.swing.common.SwingUtil;



public class TreeWithModelListener extends JFrame implements TreeModelListener{

	private static final long serialVersionUID = -6516436057733254443L;
	
	JLabel label = null;
	// 原有节点名
    String nodeName = null;

	public TreeWithModelListener() {
		super("在TreeFromTreeModelDemo的基础上增加ModelListener");
		setBounds(200,200,300,400);
		
		DefaultMutableTreeNode root = new DefaultMutableTreeNode("资源管理器");
		DefaultMutableTreeNode node1=new DefaultMutableTreeNode("我的公文包");
		DefaultMutableTreeNode node2=new DefaultMutableTreeNode("我的电脑");
		DefaultMutableTreeNode node3=new DefaultMutableTreeNode("网站");
		DefaultMutableTreeNode node4=new DefaultMutableTreeNode("Readme");
		
		DefaultTreeModel treeModel = new DefaultTreeModel(root);
		/* DefaultTreeModel类所提供的insertNodeInto()方法加入节点到父节点的数量.
         * 利用DefaultMutableTreeNode类所提供的getChildCount()方法取得目前子节点的数量.
         */
		treeModel.insertNodeInto(node1, root, root.getChildCount());
		treeModel.insertNodeInto(node2, root, root.getChildCount());
		treeModel.insertNodeInto(node3, root, root.getChildCount());
		treeModel.insertNodeInto(node4, root, root.getChildCount());

		DefaultMutableTreeNode leafNode = new DefaultMutableTreeNode("公司文件");
		treeModel.insertNodeInto(leafNode, node1, node1.getChildCount());
		//node1.add(leafNode);
		leafNode = new DefaultMutableTreeNode("私人文件");
		treeModel.insertNodeInto(leafNode, node1, node1.getChildCount());
		//node1.add(leafNode);
		leafNode = new DefaultMutableTreeNode("个人信件");
		treeModel.insertNodeInto(leafNode, node1, node1.getChildCount());
		//node1.add(leafNode);
		
		leafNode = new DefaultMutableTreeNode("本机磁盘(c:)");
		treeModel.insertNodeInto(leafNode, node2, node2.getChildCount());
		//node2.add(leafNode);
		leafNode = new DefaultMutableTreeNode("本机磁盘(d:)");
		treeModel.insertNodeInto(leafNode, node2, node2.getChildCount());
		//node2.add(leafNode);
		leafNode = new DefaultMutableTreeNode("本机磁盘(e:)");
		treeModel.insertNodeInto(leafNode, node2, node2.getChildCount());
		//node2.add(leafNode);
		
		DefaultMutableTreeNode cNode = new DefaultMutableTreeNode("搜索");
		treeModel.insertNodeInto(new DefaultMutableTreeNode("百度"), cNode, cNode.getChildCount());
		treeModel.insertNodeInto(new DefaultMutableTreeNode("Google"), cNode, cNode.getChildCount());
		treeModel.insertNodeInto(new DefaultMutableTreeNode("必应"), cNode, cNode.getChildCount());
		treeModel.insertNodeInto(cNode, node3, node3.getChildCount());
		cNode = new DefaultMutableTreeNode("门户");
		treeModel.insertNodeInto(new DefaultMutableTreeNode("新浪"), cNode, cNode.getChildCount());
		treeModel.insertNodeInto(new DefaultMutableTreeNode("搜狐"), cNode, cNode.getChildCount());
		treeModel.insertNodeInto(new DefaultMutableTreeNode("网易"), cNode, cNode.getChildCount());
		treeModel.insertNodeInto(cNode, node3, node3.getChildCount());
		
		JTree tree = new JTree(treeModel);
		//设置JTree为可编辑的
		tree.setEditable(true);
		// 设置行高
		tree.setRowHeight(20);
		// 使Tree加入检测Mouse事件，以便取得节点名称（仔细看下）
		tree.addMouseListener(new MouseEventHandler());
		tree.getModel().addTreeModelListener(this);

		
		// 改变JTree的外观 
		//tree.putClientProperty("JTree.lineStyle","None");
        //tree.putClientProperty("JTree.lineStyle","Horizontal");
		//tree.putClientProperty("JTree.lineStyle","Angled");
		
		// 取得默认的TreeCellRenderer来改变一些外观
		DefaultTreeCellRenderer cellRenderer = (DefaultTreeCellRenderer)tree.getCellRenderer();
		cellRenderer.setLeafIcon(new ImageIcon(getClass().getResource("/resources/images/red.gif")));
		cellRenderer.setOpenIcon(new ImageIcon(getClass().getResource("/resources/images/yellow.gif")));
		cellRenderer.setClosedIcon(new ImageIcon(getClass().getResource("/resources/images/green.gif")));
		
		cellRenderer.setFont(new Font("宋体", Font.PLAIN, 12));
		//cellRenderer.setBackgroundNonSelectionColor(Color.WHITE);
		cellRenderer.setBackgroundSelectionColor(Color.BLUE);
		cellRenderer.setBorderSelectionColor(Color.BLACK);
		
		JScrollPane jsp = new JScrollPane();
		jsp.setViewportView(tree);
		
		label = new JLabel("更改数据为: ");
		
		getContentPane().add(jsp, BorderLayout.CENTER);
		getContentPane().add(label, BorderLayout.SOUTH);
		//pack();
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setVisible(true);
	}

	public void treeNodesChanged(TreeModelEvent e) {
		TreePath treePath = e.getTreePath();
		System.out.println(treePath);

		// 下面这行由TreeModelEvent取得的DefaultMutableTreeNode为节点的父节点，而不是用户点选
        // 的节点，这点读者要特别注意。要取得真正的节点需要再加写下面6行代码.
		DefaultMutableTreeNode sourceParentNode = (DefaultMutableTreeNode)treePath.getLastPathComponent();

		// getChildIndices()方法会返回目前修改节点的索引值。由于我们只修改一个节点，因此节点索引值就放在index[0]
        // 的位置，若点选的节点为root node,则getChildIndices()的返回值为null
		int[] indexes = e.getChildIndices();
		if(indexes == null)
			return;
		DefaultMutableTreeNode sourceNode = (DefaultMutableTreeNode)sourceParentNode.getChildAt(indexes[0]);
		label.setText('[' + nodeName + ']'+ "更改名字为：" + (String)sourceNode.getUserObject());
	}

	public void treeNodesInserted(TreeModelEvent e) {}

	public void treeNodesRemoved(TreeModelEvent e) {}

	public void treeStructureChanged(TreeModelEvent e) {}

	class MouseEventHandler extends MouseAdapter {
		@Override
		// 注意下面的两种方法取得当前的treeNode，一种是tree.getSelectionPath()；一种比较另类，通过鼠标点击的location定位TreePath
		public void mousePressed(MouseEvent e) {

			JTree tree = (JTree)e.getSource();
			
			/* JTree的getRowForLocation()方法会返回鼠标点取得地点（location）对应的节点的行索引值。
			 * 如果鼠标点取的location没有组件，则会返回-1
			 * 例如本例中，“本机磁盘(D:)”的列索引值为4,此索引值会随着其他数据夹的打开或收起而变更
			 * 但“资源管理器”的列索引值恒为0. 
			 */
			//int row4Location = tree.getRowForLocation(e.getX(), e.getY());
			//if(row4Location == -1)
			//	return;
			/* JTree的getPathForRow()方法会取得从root node到点选节点的一条path,此path为一条直线，如程序运行的图示
             * 若你点选“本机磁盘(E:)”,则Tree Path为"资源管理器"-->"我的电脑"-->"本机磁盘(E:)",因此利用TreePath
             * 的getLastPathComponent()方法就可以取得所点选的节点.
             */
			//TreePath treepath = tree.getPathForRow(row4Location);
			
			TreePath treepath=tree.getSelectionPath();
			if(treepath != null)
			{
				TreeNode treenode = (TreeNode) treepath.getLastPathComponent();
				nodeName = treenode.toString();
			}
			label.setText("你选取了:" + nodeName);
		}
	}
	
	public static void main(String[] args) {
		SwingUtil.setLookAndFeel();
		new TreeWithModelListener();
	}
}
